﻿import type { RequestOptions } from '@@/plugin-request/request';
import type { RequestConfig } from '@umijs/max';
import { history } from '@umijs/max';
import { message } from 'antd';
import { isDev } from './utils/dev';
import { getToken, removeToken } from './utils/token';

// eslint-disable-next-line no-var
var API_address = !isDev()
  ? {
      http: 'https://cqgxq.ljsyy.net',
      // http: 'http://sbbpns.natappfree.cc',
      // http: 'http://8daswc.natappfree.cc',
    }
  : {
      // http: 'http://localhost:8181',
      // http: 'http://172.20.129.125:8181',
      http: 'http://172.20.129.78:8181',

      // http: 'https://cqgxq.ljsyy.net',
      // http:'http://172.20.129.177:8180',
      // http: 'http://172.20.129.112:8181',
      // http: 'http://172.20.129.177:8181',0
      // http: 'https://yq.ljsyy.net',
      // http: 'https://cqgxq.ljsyy.net',
      // http: 'http://pnymih.natappfree.cc',
    };

export function getApi(): string {
  return `${API_address.http}/xtbssink/app`;
}

export function getHttp(): string {
  return API_address.http;
}

const loginPath = '/user/login';

const StatusCodeMessage = {
  0: '请求发生错误，请联系管理员',
  200: '服务器成功返回请求的数据',
  203: '返回数据错误，请联系管理员',
  500: '服务器发生错误，请联系管理员',
  502: '网关错误',
  503: '服务不可用，服务器暂时过载或维护',
  504: '网关超时',
};
// 与后端约定的响应数据格式
interface ResponseStructure {
  code: number;
  msg: string;
  data?: any;
}

/**
 * @name 错误处理
 * pro 自带的错误处理， 可以在这里做自己的改动
 * @doc https://umijs.org/docs/max/request#配置
 */
export const requestConfig: RequestConfig = {
  baseURL: getApi(),
  // 请求拦截器
  requestInterceptors: [
    (config: RequestOptions) => {
      const authHeader = { satoken: getToken() };
      // 拦截请求配置，进行个性化处理。
      return { ...config, headers: authHeader };
    },
  ],

  // 响应拦截器
  responseInterceptors: [
    (response) => {
      if (response.status === 200) {
        const disposition = response.headers['content-disposition'];

        if (disposition) {
          const splitDis = disposition.split(';');
          if (splitDis[0] === 'attachment') {
            const fileNameDefault = splitDis[1].split('filename=')[1];
            const fileNameUnicode = disposition.split('filename*=')[1];
            const filename = fileNameUnicode
              ? decodeURIComponent(fileNameUnicode.split("''")[1])
              : fileNameDefault;

            const content = response.data as ArrayBuffer;

            //在请求处 添加 responseType: 'blob'
            const blob = new Blob([content]);

            const link = document.createElement('a');
            link.style.display = 'none';
            link.href = URL.createObjectURL(blob);
            link.download = filename;
            link.click();
            URL.revokeObjectURL(link.href);
          }
          return response;
        }

        // 拦截响应数据，进行个性化处理
        const { code, msg, data } = response.data as unknown as ResponseStructure;
        if (code === undefined) {
          const error: any = new Error(msg);
          error.name = 'BizError';
          error.info = { code: 201 };
          throw error; // 抛出自制的错误
        } else if (code === 0) {
          //请求成功
          /**
           * 50:无效的TOKEN
           * 1104:用户未分配角色，请联系管理员
           * 7:该用户已被绑定，请联系管理员或回到登录页面
           * 12:该用户绑定的单位已经禁用
           * 13:已切换单位
           * 15:绑定账户错误
           * 16:请等待管理员审核

           */
          return response;
        } else if (code === 2) {
          //验证过期，请重新登录
          removeToken();
          history.push(loginPath);
          return response;
        } else if (code === 12) {
          //验证过期，请重新登录
          removeToken();
          history.push(loginPath);
          message.warning(msg);
          return response;
        }
        if (code === 50) {
          //验证过期，请重新登录
          removeToken();
          message.error(msg);
          history.push(loginPath);
          return response;
        } else {
          message.error(msg);
        }
      }
      return response;
    },
  ],

  // 错误处理： umi@3 的错误处理方案。
  errorConfig: {
    // 错误抛出
    errorThrower: (res) => {
      const { success, data, errorCode, errorMessage, showType } =
        res as unknown as ResponseStructure;
      if (!success) {
        const error: any = new Error(errorMessage);
        error.name = 'BizError';
        error.info = { errorCode, errorMessage, showType, data };
        throw error; // 抛出自制的错误
      }
    },
    // 错误接收及处理
    errorHandler: (error: any, opts: any) => {
      if (opts?.skipErrorHandler) throw error;
      // 我们的 errorThrower 抛出的错误。
      if (error.name === 'BizError') {
        const errorInfo: ResponseStructure | undefined = error.info;
        if (errorInfo) {
          const { code } = errorInfo;
          message.error(StatusCodeMessage[code]);
        }
      } else if (error.response) {
        // Axios 的错误
        // 请求成功发出且服务器也响应了状态码，但状态代码超出了 2xx 的范围
        message.error(StatusCodeMessage[error.response.status]);
      } else if (error.request) {
        // 请求已经成功发起，但没有收到响应
        // \`error.request\` 在浏览器中是 XMLHttpRequest 的实例，
        // 而在node.js中是 http.ClientRequest 的实例
        message.error('None response! Please retry.');
      } else {
        // 发送请求时出了点问题
        message.error('Request error, please retry.');
      }
    },
  },
};
